package org.aceor.mddal.perf;

import org.aceor.mddal.client.jdbc.DataSourceFacade;
import org.aceor.mddal.config.sharding.LogicTable;
import org.aceor.mddal.gateway.router.Router;
import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Test;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by lxue on 16/5/11.
 */
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Fork(1)
@State(Scope.Benchmark)//多线程共享
@Threads(10)
@Warmup(iterations = 3, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
public class Main {

    private static final String CURRENT_CLASS_NAME = Main.class.getSimpleName();

    ApplicationContext applicationContext;
    Router router;
    BasicDataSource basicDataSource;
    DataSourceFacade myDataSourceFacade;
    AtomicInteger count;

    @Setup
    public void init() {
        applicationContext = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
        router = Router.getInstance(applicationContext.getBean(LogicTable.class));
        basicDataSource = applicationContext.getBean(BasicDataSource.class);
        myDataSourceFacade = applicationContext.getBean(DataSourceFacade.class);
        count = new AtomicInteger(0);
    }

    @Benchmark
    public void test_empty_method() {
        emptyMethod();
    }

    public  void emptyMethod() {

    }
    /**
     * 结论: 超时时间定3秒
     * 0. mysql最大连接151
     * 1. dbcp最大连接数231
     * 2. 200ms后释放连接
     */
    @Benchmark
    public void test_get_connection_by_dbcp() {
        Connection connection = null;
        try {
            connection= basicDataSource.getConnection();
//            count.incrementAndGet();
//            System.out.println(Thread.currentThread().getName()+"-sleep");
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != connection) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    @Benchmark
    public void test_get_connection_by_my_ds() throws SQLException {
        myDataSourceFacade.getConnection().createStatement().execute("");
    }

//    @Test
//    public void test_init() {
//        assertNotNull(applicationContext);
//        assertNotNull(router);
//        assertNotNull(basicDataSource);
//        assertNotNull(myDataSourceFacade);
//    }

    @Test
    public void benchmark_test_empty_method() throws Exception {
        Options opt = new OptionsBuilder()
                .include(CURRENT_CLASS_NAME + ".test_empty_method")
                .build();

        new Runner(opt).run();
    }

    @Test
    public void benchmark_test_get_connection_by_dbcp() throws Exception {
        Options opt = new OptionsBuilder()
                .include(CURRENT_CLASS_NAME + ".test_get_connection_by_dbcp")
                .build();

        new Runner(opt).run();
    }


    /**
     * 场景1: 多个读写并发时,显出读写分离的优势.
     *
     * 场景2:
     */
}
